﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using FeatureModelTool.FeatureModelView;
using FeatureModelTool.FeatureModelView.TreeViewItems;
using TreeGraphicalControl;
using FeatureModelCore;
using FeatureModelTool.Windows;
using FeatureModelCore.FMAnalyzer;
using FeatureModelCore.Configuration;
using System.Xml.Linq;
using System.IO;
using FeatureModelCore.Optimized;

namespace FeatureModelTool.FileView
{
    /// <summary>
    /// Interaction logic for FeatureModelTreeViewTab.xaml
    /// </summary>
    public partial class FeatureModelTreeViewTab : TabItem, IMainTab
    {
        public bool Dirty { get { return this.FeatureModelView.TreeInstance.Dirty; } }
        public static FeatureTreeViewItemGenerator Generator;
        static FeatureModelTreeViewTab()
        {
            Generator = new FeatureTreeViewItemGenerator(
                TreeItem_Root.ConstructTreeItem, TreeItem_Root.GenerateContext);
            // register Group Relationship
            ItemRegister gRelationshipRegister = new ItemRegister(typeof(FeatureTreeGroupRelationship)
                , typeof(TreeItem_GroupRelationship)
                , TreeItem_GroupRelationship.ConstructTreeItem
                , TreeItem_GroupRelationship.GenerateContext);
            Generator.Register(gRelationshipRegister);
            // register Relationship
            //ItemRegister relationshipRegister = new ItemRegister(typeof(FeatureTreeRelationship)
            //    , typeof(TreeItem_Relationship)
            //    , TreeItem_Relationship.ConstructTreeItem
            //    , TreeItem_Relationship.GenerateContext);
            //Generator.Register(relationshipRegister);
            // register Node
            ItemRegister nodeRegister = new ItemRegister(typeof(FeatureTreeNode)
                , typeof(TreeItem_Node)
                , TreeItem_Node.ConstructTreeItem
                , TreeItem_Node.GenerateContext);
            Generator.Register(nodeRegister);
            // register Property
            ItemRegister propertyRegister = new ItemRegister(typeof(FeatureNodeProperty)
                , typeof(TreeItem_Property)
                , TreeItem_Property.ConstructTreeItem
                , TreeItem_Property.GenerateContext);
            Generator.Register(propertyRegister);
        }
        public FeatureTreeView TreeView { get { return this.FeatureModelView; } }
        public FeatureModelTreeViewTab()
        {
            InitializeComponent();
            this.FeatureModelView.BindGenerator(Generator);

            #region Menu Context
            MenuItem createCons = new MenuItem()
            {
                Name="CreateConstraint",
                Header="New Cross Tree Constraint"
            };
            createCons.Click += new RoutedEventHandler(createConstraint_EventHandler);

            MenuItem save = new MenuItem()
            {
                Name = "save",
                Header = "Save"
            };
            save.Click += new RoutedEventHandler(save_EventHandler);

            MenuItem close = new MenuItem()
            {
                Name = "close",
                Header = "Close"
            };
            close.Click += new RoutedEventHandler(close_EventHandler);

            MenuItem expand = new MenuItem()
            {
                Name = "expandAll",
                Header = "Expand All Items"
            };
            expand.Click += new RoutedEventHandler(expandAllItems_EventHandler);

            MenuItem analyze = new MenuItem()
            {
                Name = "Analyze",
                Header = "Analyze"
            };

            //MenuItem valid = new MenuItem()
            //{
            //    Name = "Valid",
            //    Header = "Valid Feature Model"
            //};
            //valid.Click += new RoutedEventHandler(valid_EventHandler);
            MenuItem allProduct = new MenuItem()
            {
                Name = "AllProduct",
                Header = "All Products"
            };
            allProduct.Click += new RoutedEventHandler(allProduct_EventHandler);
            MenuItem generateOptimizedFM = new MenuItem()
            {
                Name = "generateOptimizedFM",
                Header = "Generate Optimized Feature Model Tree"
            };
            generateOptimizedFM.Click += new RoutedEventHandler(generateOptimizedFM_EventHandler);
            MenuItem generateConfig = new MenuItem()
            {
                Name = "generateConfig",
                Header = "Generate Config"
            };
            generateConfig.Click += new RoutedEventHandler(generateConfig_EventHandler);

            //analyze.Items.Add(valid);
            analyze.Items.Add(allProduct);
            analyze.Items.Add(generateOptimizedFM);
            analyze.Items.Add(generateConfig);

            this.ContextMenu = new ContextMenu();
            this.ContextMenu.Items.Add(close);
            this.ContextMenu.Items.Add(save);
            this.ContextMenu.Items.Add(createCons);
            this.ContextMenu.Items.Add(new Separator());            
            this.ContextMenu.Items.Add(expand);
            this.ContextMenu.Items.Add(new Separator());
            this.ContextMenu.Items.Add(analyze);
            #endregion
        }

        #region Context Menu Event Handler
        /// <summary>
        /// close
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void close_EventHandler(object sender, RoutedEventArgs e)
        {
            if (this.Dirty)
            {
                ClosingWarningDialog dialog = new ClosingWarningDialog();
                dialog.ShowDialog();
                if (dialog.ToSave == true)
                {
                    this.SaveInstance();
                }
                if (dialog.ToClose == false)
                {
                    return;
                }
            }

            TabControl tabControl = (TabControl)this.Parent;
            tabControl.Items.Remove(this);
        }
        /// <summary>
        /// save
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void save_EventHandler(object sender, RoutedEventArgs e)
        {
            this.SaveInstance();
        }
        /// <summary>
        /// Save
        /// </summary>
        public void SaveInstance()
        {
            ((FeatureModelTree)this.FeatureModelView.TreeInstance).Save();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void expandAllItems_EventHandler(object sender, RoutedEventArgs e)
        {
            this.FeatureModelView.ExpandAll();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        //protected void valid_EventHandler(object sender, RoutedEventArgs e)
        //{
        //    FeatureModelTree fmTree = (FeatureModelTree)this.FeatureModelView.TreeInstance;
        //    bool validIntegrity = fmTree.ValidFeatureModelIntegrity();
        //    bool validOptimizedTree = fmTree.Analyzer.OptimizedTree.ValidAllCrossTreeConstraint();
        //    if (validIntegrity && validOptimizedTree)
        //    {
        //        return;
        //    }
        //    MessageBox.Show("Invalid Feature Model");
        //}
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void createConstraint_EventHandler(object sender, RoutedEventArgs e)
        {
            try
            {
                FeatureModelTree fmTree = (FeatureModelTree)this.FeatureModelView.TreeInstance;
                NewConstraintsDialog dia = new NewConstraintsDialog(fmTree.AllFeatureNodes);
                dia.ShowDialog();
                if (dia.Dirty == false)
                {
                    return;
                }

                fmTree.CreateConstraint(dia.NodeA.ID, dia.NodeB.ID, dia.ConstraintType);
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.Message + exp.StackTrace);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void allProduct_EventHandler(object sender, RoutedEventArgs e)
        {
            try
            {
                FeatureModelTree fmTree = (FeatureModelTree)this.FeatureModelView.TreeInstance;
                FMProductCollection allProducts = fmTree.AllProducts();

                AllProductsWindows dialog = new AllProductsWindows(allProducts);
                dialog.Show();
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.Message + exp.StackTrace);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void generateConfig_EventHandler(object sender, RoutedEventArgs e)
        {
            FeatureModelTree fmTree = (FeatureModelTree)this.FeatureModelView.TreeInstance;
            ConfigFeatureModel configFm = new ConfigFeatureModel(fmTree);
            XDocument xdoc = configFm.ToXDoc();
            string fileFullPath = fmTree.FolderPath + "\\" + fmTree.Root.Name + ".config";
            using (StreamWriter writer = File.CreateText(fileFullPath))
            {
                writer.Write(xdoc);
            }

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void generateOptimizedFM_EventHandler(object sender, RoutedEventArgs e)
        {
            //FeatureModelTree fmTree = (FeatureModelTree)this.FeatureModelView.TreeInstance;
            //OptimizedFeatureModel optimizedTree = fmTree.Analyzer.OptimizedTree;
            //FeatureModelTree optimizedFm = optimizedTree.ToFeatureModelTree();
            //string fileFullPath = fmTree.FolderPath + "\\optimized_" + fmTree.Root.Name + ".fm";
            //optimizedFm.SaveAs(fileFullPath);
        }
        #endregion
    }
}
